package com.reflex.method;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Author: lizehui
 * @Description: Class类的常用方法-详细版
 * @Date: 2022/11/18/17:45
 */
public class ClassMethodDetail {

    public static void main(String[] args) throws Exception{

    }

    //反射基础
    @Test
    public void api_01() throws Exception{

        //得到Class对象
        Class<?> personClass = Class.forName("com.reflex.dao.Person");
        //获取全类名 com.reflex.dao.Person
        System.out.println(personClass.getName());
        //获取简单类名 Person
        System.out.println(personClass.getSimpleName());
        //获取所有本类和父类的public属性
        System.out.println("---------获取所有本类和父类的public属性名---------");
        Field[] fields = personClass.getFields();
        for (Field f: fields) {
            System.out.println(f.getName());
        }
        //获取本类中所有属性
        System.out.println("----------------获取本类中所有属性----------------");
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field f: declaredFields) {
            System.out.println(f.getName());
        }
        //获取本类和父类的所有public方法
        System.out.println("-----------获取本类和父类的所有public方法-----------");
        Method[] methods = personClass.getMethods();
        for (Method m: methods) {
            System.out.println(m.getName());
        }
        //获取本类中所有方法
        System.out.println("-----------------获取本类中所有方法-----------------");
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method m: declaredMethods) {
            System.out.println(m.getName());
        }
        //获取本类有所有public构造器
        System.out.println("-------------获取本类有所有public构造器-------------");
        Constructor<?>[] constructors = personClass.getConstructors();
        for (Constructor<?> c : constructors) {
            System.out.println(c.getName());
        }
        //获取本类有所有构造器
        System.out.println("-----------------获取本类有所有构造器-----------------");
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> c : declaredConstructors) {
            System.out.println(c.getName());
        }
        //获取包信息
        System.out.println("---------------------获取包信息---------------------");
        System.out.println(personClass.getPackage());
        //以Class形式返回父类信息
        System.out.println("-----------------以Class形式返回父类信息-----------------");
        Class<?> superclass = personClass.getSuperclass();
        System.out.println(superclass);
        //以Class[]形式返回接口信息
        System.out.println("----------------以Class[]形式返回接口信息----------------");
        Class<?>[] interfaces = personClass.getInterfaces();
        for (Class<?> c : interfaces) {
            System.out.println(c);
        }
        //以Annotation形式返回注解信息
        System.out.println("----------------以Annotation形式返回注解信息----------------");
        Annotation[] annotations = personClass.getAnnotations();
        for (Annotation a : annotations) {
            System.out.println(a);
        }

    }

    //反射获取属性
    @Test
    public void api_02() throws Exception{

        /**
         * @Description: 获取类中的属性名、修饰符值、属性类型
         * 默认修饰符default 0、public 1、private 2、protect 4、static 8、final 16
         * public(1) static(8) => 9
         */
        System.out.println("----------------获取类中的属性名、修饰符值、属性类型----------------");
        //得到Class对象
        Class<?> personClass = Class.forName("com.reflex.dao.Person");
        Field[] declaredFields = personClass.getDeclaredFields();
        for (Field f: declaredFields) {
            System.out.println("属性名=" + f.getName()
                    + " 属性修饰符=" + f.getModifiers()
                    + " 属性类型=" + f.getType());
        }
    }

    //反射获取方法
    @Test
    public void api_03() throws Exception{

        /**
         * @Description:
         * default 0、public 1、private 2、protect 4、static 8、final 16
         * public(1) static(8) => 9
         */
        System.out.println("----------------获取类中的方法的修饰符值、方法返回值类型、方法入参类型----------------");
        //得到Class对象
        Class<?> personClass = Class.forName("com.reflex.dao.Person");
        //获取所有方法
        Method[] declaredMethods = personClass.getDeclaredMethods();
        for (Method m: declaredMethods) {
            System.out.println(m.getName() + "方法"
                    + " 方法修饰符=" + m.getModifiers()
                    + " 方法返回值类型=" + m.getReturnType());
            Class<?>[] parameterTypes = m.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println(m.getName() + "方法的入参类型" + parameterType);
            }
        }


    }

    //反射获取构造器
    @Test
    public void api_04() throws Exception{
        //得到Class对象
        Class<?> personClass = Class.forName("com.reflex.dao.Person");
        //获取所有构造器
        Constructor<?>[] declaredConstructors = personClass.getDeclaredConstructors();
        for (Constructor<?> c : declaredConstructors) {
            System.out.println("方法中的构造器" + c.getName());

            Class<?>[] parameterTypes = c.getParameterTypes();
            for(Class<?> p : parameterTypes){
                System.out.println(c.getName() + "构造器入参" + p);
            }
        }

    }

}


